<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
    <meta http-equiv="content-language" content="zh-CN" />
    

    
    <meta name="viewport" content="width=device-width, initial-scale=0.5">
    

    
    <title>data.table -- 2基本概念</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
    
    
    
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">

    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">

    <link rel="stylesheet" href="/css/stylesheet.css">
    <link rel="stylesheet" href="/css/home.css">

    
    
        <style type="text/css">
        body { background-color: #fbf6ec;}
        </style>
    
    
                
        
        
            <link rel="stylesheet" href="/css/main.css"/>
        




        
        
        
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.min.css"  />
         
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js"></script>
        
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/r.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/yaml.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/latex.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/matlab.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/mathematica.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/julia.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/julia-repl.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/powershell.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/bash.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/shell.min.js"></script>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/languages/python.min.js"></script>
        
        <script>hljs.initHighlightingOnLoad();</script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
     
     
</head>


<body>
    <script>
        window.addEventListener("resize", resizeThrottler, false);

        var resizeTimeout;
        function resizeThrottler() {
        
        if ( !resizeTimeout ) {
            resizeTimeout = setTimeout(function() {
            resizeTimeout = null;
            actualResizeHandler();
        
            
            }, 66);
        }
        }
        actualResizeHandler()
        function actualResizeHandler() {
                if (/mobile/i.test(navigator.userAgent) || /android/i.test(navigator.userAgent))
                {
                    document.body.classList.add('mobile');
                }else{
                    document.body.classList.remove('mobile');  
                }
    }</script>

    
      
      
            <nav class="navbar navbar-default navbar-static-top" style="opacity: .9" role="navigation">
        <div class="container-fluid">
            
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">

                    <span class="sr-only">Toggle navigation</span>
                    <span class="big-icon icon-bar"></span>
                    <span class="big-icon icon-bar"></span>
                    <span class="big-icon icon-bar"></span>

                </button>
                <a class="navbar-brand" href="/">zsc</a>
            </div>

            <div class="navbar-collapse collapse" id="bs-example-navbar-collapse-1" style="height: auto;">
                <ul class="nav navbar-nav navbar-right" style="font-size: 100%">
                    
                        
                            
                            <li class=""><a href="/about/">About</a></li>
                            
                            <li class=""><a href="/categories/">Categories</a></li>
                            
                            <li class=""><a href="/">Home</a></li>
                            
                            <li class=""><a href="/tags/">Tags</a></li>
                            
                            <li class=""><a href="/issue/">存在的问题</a></li>
                            
                        
                    
                </ul>
            </div>
        </div>
    </nav>










<div class="inner">
    



    <div class="blog-post">
        
                <div>
            <h2 align="center" id = "singe-h2">
                data.table -- 2基本概念
                <time>
                    <br>
                    <span> 
                        <i class="fa fa-user-edit" style="color:#888;font-size: 80%;"></i>
                        zsc 
                    </span>
                    &nbsp 
                    <span>                 
                        <i class="fa fa-calendar-alt" style="color:#888;font-size: 80%;"></i>
                        2018-01-17 
                    </span>
                </time>
                
                
                <div>
                    <ul class="tags">
                        
                        <span>标签:</span>
                        <li><a class="link" href="/tags/r"> #r </a></li><li><a class="link" href="/tags/data.table"> #data.table </a></li>
                        
                        <span> </span>
                        
                    </ul>
                    
                </div>
            </h2>
        </div>
    
        
        <section id="content">
            <h1 id="datatable基本概念和其余函数---还需要修改">data.table基本概念和其余函数&mdash;还需要修改</h1>
<p><code>set*  </code> 函数族 会改变原有的数据，没有返回值，在<code>data.table</code>里，操作符<code>&quot;:=&quot;</code>和所有的以<code>set</code>开头函数（比如<code>setkey</code>,<code>setorder</code>,<code>setname</code>等）一样，它们都会更新输入的原数据。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">library</span>(data.table)
</span></span><span style="display:flex;"><span>iris_dt <span style="color:#f92672">=</span> <span style="color:#a6e22e">data.table</span>(iris)
</span></span><span style="display:flex;"><span><span style="color:#75715e"># setnames(DT,oldnames,newnames) # 改变DT的列名oldnames,newnames为向量即变量</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#改变列的顺序</span>
</span></span><span style="display:flex;"><span>col_names <span style="color:#f92672">=</span> <span style="color:#a6e22e">colnames</span>(iris_dt)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">setcolorder</span>(iris_dt,col_names[5<span style="color:#f92672">:</span><span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 更改某行某列的值,即更新元素的值</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">set</span>(iris_dt,<span style="color:#ae81ff">1</span>,<span style="color:#ae81ff">1</span>,<span style="color:#66d9ef">NA</span>)<span style="color:#75715e"># 更改1行1列的值为NA</span>
</span></span></code></pre></div><h2 id="1键主键的概念">1、键（主键）的概念</h2>
<ol>
<li><code>data.table</code>从来不使用行名。<code>data.table</code>类似有行名的形式为<code>1:，2: , ...</code></li>
<li><strong>主键会对筛选的列进行重排序</strong></li>
<li>我们把data.table数据中的行名叫做键（或主键），他类似于python的字典，使用键值对类型查找数据，键要求唯一，每一行有且只有一个键。但是R中的键可以用多个甚至可以重复，键就相当于索引，通过键进行数据的查找</li>
<li><code>setkey()</code> 和 <code>setkeyv()</code>可以直接更新输入的data.table，就和上一讲中的操作符&quot;:=&ldquo;一样。它们没有返回值。</li>
<li>这个主键和其它语言不一样，例如python的键，唯一，在r中任意列都能使用setkey()来设置主键</li>
</ol>
<pre tabindex="0"><code class="language-{r,message=F,warning=F}" data-lang="{r,message=F,warning=F}">library(data.table)
mtcars_dt &lt;- data.table(mtcars)  # 可以看出mtcars数据集中的行名没有了，替而代之为1: ，2:

# 若想保留行名，设置keep.rownames = T，当keep.rowname＝&#34;new&#34;时，列名改为new即可
mtcars_dt &lt;- data.table(mtcars,keep.rownames = T)#默认创建一个叫做 rn的列，并且将行名赋值给这一列。
mtcars_dt
</code></pre><h4 id="12设置获取使用主键">1.2、设置／获取／使用主键</h4>
<p>怎么将数据中的某一列设置为主键呢？&mdash;setkey()函数</p>
<ul>
<li><code>setkey(DT, key) </code>将DT中的key列设置为主键，但是类行名 1:，2:,&hellip;,不会发生改变,</li>
<li>上面等价<code>  setkeyv(DT, &quot;key&quot;)</code> ，也将DT中的key列设置为主键</li>
<li>一旦将某一列设置成data.table的主键，就可以在参数i里指定 <code>.()</code>来subset那些主键了(就可以进行行筛选了)。我们还是用mtcars数据集，我们增加一个新列new</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">mtcars_dt &lt;- data.table(mtcars)
mtcars_dt[,new:=Sys.Date()+1:32] #增加一列new，内容为时间
setkey(mtcars_dt,new)
mtcars_dt   # 类似行名并没有发生改变，
mtcars_dt[.(Sys.Date()+1)]
key(mtcars_dt)    #查询设置主键的列名


# 也可以在r中任意列都能使用setkey()来设置主键
setkey(mtcars_dt,cyl,vs)	#会把先前设置的new主键给覆盖掉
mtcars_dt[.(4,1)]	#如果主键是字符型的列，那么可以省略 .()
key(mtcars_dt)	#查询设置主键的列名

haskey(mtcars_dt) # 返回TF值，检查是否有Key
</code></pre><h2 id="2-二级索引">2 、二级索引</h2>
<p>二级索引和data.table的主键类似（<strong>二级索引不重排序，主键会重排序</strong>），但有以下两点不同：</p>
<ul>
<li>它不会再内存里将整个data.table重新排序（<code>setkey</code>会）。它只会计算某列的顺序，将这个顺序向量保存在一个额外的，叫做index的属性里面。</li>
<li>一个data.table可以有多个二级索引，我们把主键与二级索引提取行方法进行对比</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}"># 设置主键的过程
mtcars_dt &lt;- data.table(mtcars)
mtcars_dt[,new:=Sys.Date()+1:32] #增加一列new，内容为时间
setkey(mtcars_dt,cyl,vs)	#设置主键
mtcars_dt[.(4,1)]	#提取cyl==4,vs==1的所有行
</code></pre><pre tabindex="0"><code class="language-{r}" data-lang="{r}">#  设置二级索引的过程--方法1
mtcars_dt &lt;- data.table(mtcars)
mtcars_dt[,new:=Sys.Date()+1:32] #增加一列new，内容为时间
setindex(mtcars_dt,cyl,vs)# 把cyl,vs两列都设置二级索引的过程--方法1
mtcars_dt   # 等价 setindexv(mtcars_dt,&#34;cyl&#34;,&#34;vs&#34;)

#注意mtcars_dt实际上没有按照cyl列的升序重新排列。还记得吗？setkey()会重新排序！
# setindex(mtcars_dt,NULL)  会删除所有的二级索引。
indices(mtcars_dt,vectors = FALSE)#  获取数据的二级索引,  默认为FALSE
setindex(mtcars_dt,new) #再次建立一个二级索引
indices(mtcars_dt)# 查看二级索引，可以发现在原有的二级索引上追加了新的索引，不会覆盖，还记得setkey(mtcars_dt,cyl,vs)会把先前设置的new主键给覆盖掉
</code></pre><ul>
<li>参数on能自动创建并重用二级索引－－等价setindex() 函数</li>
<li>通过创建索引进行subset。每次都能节省setindex()的时间。</li>
<li>通过检查属性，可以简单地重用已经存在的二级索引。</li>
<li>语法简单。</li>
<li>在参数i里面指定取值，在参数on里面指定列名。参数on必须是一个字符型的向量。</li>
<li>注意参数on也可以用来指定主键。事实上，为了更佳的可读性，我们鼓励在参数on里面指定主键。</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">#  设置二级索引的过程--方法2
mtcars_dt &lt;- data.table(mtcars)
mtcars_dt[,new:=Sys.Date()+1:32] #增加一列new，内容为时间
mtcars_dt[.(6),on=&#34;cyl&#34;]#当为字符时，可以省略.()
mtcars_dt[.(6,3),on=c(&#34;cyl&#34;,&#34;gear&#34;)]#同时满足cyl=6,gear=3的行
</code></pre><p><strong>主键与索引用来提取行，对参数i处理的一个变形，可以结合j，by参数进行处理</strong></p>
<h2 id="3参数mult和nomatch">3、参数mult和nomatch</h2>
<h5 id="a-参数mult默认为all">a) 参数mult，默认为“all”</h5>
<p>对于每次查询指定所有符合条件的行都被返回，若只返回第一行／最后一行设置为“first”或“last”。</p>
<h5 id="b参数nomatch-默认为na">b)参数nomatch 默认为NA</h5>
<p>指定在没有找到符合条件的数据的情况下，是返回NA。设置 nomatch = 0L 跳过哪些不存在的数据</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">library</span>(data.table)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">library</span>(magrittr)
</span></span><span style="display:flex;"><span>iris_dt <span style="color:#f92672">=</span> <span style="color:#a6e22e">data.table</span>(iris) 
</span></span><span style="display:flex;"><span>iris_dt<span style="color:#a6e22e">[.</span>(<span style="color:#ae81ff">5.1</span>), on<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;Sepal.Length&#39;</span>] <span style="color:#f92672">%&gt;%</span> <span style="color:#a6e22e">head</span>(<span style="color:#ae81ff">3</span>)
</span></span><span style="display:flex;"><span>iris_dt<span style="color:#a6e22e">[.</span>(<span style="color:#ae81ff">100</span>), on<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;Sepal.Length&#39;</span>] <span style="color:#75715e"># 没有找到Sepal.Length==100 的行,则返回NA</span>
</span></span><span style="display:flex;"><span>iris_dt<span style="color:#a6e22e">[.</span>(<span style="color:#ae81ff">100</span>), on<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;Sepal.Length&#39;</span>, nomatch <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>]
</span></span></code></pre></div><h2 id="4数据融合">4、数据融合</h2>
<h4 id="a-函数melt拆数据">a) 函数melt－－拆数据</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">melt</span>(data, id.vars, measure.vars, 
</span></span><span style="display:flex;"><span>    variable.name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;variable&#34;</span>, value.name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;value&#34;</span>, 
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">...</span>, na.rm <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>, variable.factor <span style="color:#f92672">=</span> <span style="color:#66d9ef">TRUE</span>, 
</span></span><span style="display:flex;"><span>    value.factor <span style="color:#f92672">=</span> <span style="color:#66d9ef">FALSE</span>, 
</span></span><span style="display:flex;"><span>    verbose <span style="color:#f92672">=</span> <span style="color:#a6e22e">getOption</span>(<span style="color:#e6db74">&#34;datatable.verbose&#34;</span>))
</span></span></code></pre></div><ul>
<li>参数 measure.vars 指定了想要拆分（或合并）的列。我们也可以指定索引而不是列名。</li>
<li>默认variable列是 factor类型的。如果你想返回一个字符型的向量，可以将参数 variable.factor 设为 FALSE。参数 variable.factor 是data.table的函数melt() 里独有的，增强包reshape2 里面没有这个参数。</li>
<li>variable.name = &ldquo;variable&rdquo;, value.name = &ldquo;value&rdquo;, 会把转化后的列被自动命名为 variable 和 value（默认值）。</li>
<li>在结果里，函数melt() 保持了原来列的属性。</li>
</ul>
<h4 id="b-函数dcast和数据">b) 函数dcast－－和数据</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">dcast</span>(data, formula, fun.aggregate <span style="color:#f92672">=</span> <span style="color:#66d9ef">NULL</span>, sep <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;_&#34;</span>, 
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">...</span>, margins <span style="color:#f92672">=</span> <span style="color:#66d9ef">NULL</span>, subset <span style="color:#f92672">=</span> <span style="color:#66d9ef">NULL</span>, fill <span style="color:#f92672">=</span> <span style="color:#66d9ef">NULL</span>, 
</span></span><span style="display:flex;"><span>    drop <span style="color:#f92672">=</span> <span style="color:#66d9ef">TRUE</span>, value.var <span style="color:#f92672">=</span> <span style="color:#a6e22e">guess</span>(data),
</span></span><span style="display:flex;"><span>    verbose <span style="color:#f92672">=</span> <span style="color:#a6e22e">getOption</span>(<span style="color:#e6db74">&#34;datatable.verbose&#34;</span>))
</span></span></code></pre></div><ul>
<li>函数 dcast() 使用了操作符“~”，左边是作为 id.vars 的列，右边是作为 measure.vars 的列。</li>
<li>参数 value.var 指定了需要被分拆扩张的列。</li>
<li>函数 dcast() 也会在结果中尽量保持原来的属性</li>
<li>可以给参数 fun.aggregate 传递一个函数。当操作符“~”不方便指定列名的时候，这个功能特别有用。</li>
</ul>
<h2 id="5by的其他参数技巧">5、by的其他参数技巧</h2>
<ul>
<li><strong>rleid</strong>   &mdash;- 计算某向量的游程数（游程数：每次连续作为一组）（可以结合by参数使用）</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">DT = data.table(grp=rep(c(&#34;A&#34;, &#34;B&#34;, &#34;C&#34;, &#34;A&#34;, &#34;B&#34;), c(2,2,3,1,2)), value=1:10)
DT
rleid(DT$grp) # 获取DT$grp的游程数，返回一个和原向量等长的向量
rleidv(DT, &#34;grp&#34;) # 与上面等价

rleid(DT$grp, prefix=&#34;grp&#34;) # 在游程数前面加&#34;grp&#34;

# 也可以按游程数进行分组，并计算其游程数的个数等操作
DT[, .N, by=.(rleid(grp))]
</code></pre><ul>
<li><strong>rowid</strong>  &mdash;&ndash;某个值在向量中出现的次数，出现第几次就显示为几</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">
DT = data.table(x=c(20,10,10,30,30,20), y=c(&#34;a&#34;, &#34;a&#34;, &#34;a&#34;, &#34;b&#34;, &#34;b&#34;, &#34;b&#34;), z=1:6)
DT
rowid(DT$x) # 1,1,2,1,2,2
rowidv(DT, cols=&#34;x&#34;) # 和上面等价

rowid(DT$x, prefix=&#34;group&#34;) # 数字前面加&#34;group&#34;

# 多列组合,看每一行的所有元素是否相同，相同则计数+1
rowid(DT$x, DT$y)#等价rowidv(DT, cols=c(&#34;x&#34;,&#34;y&#34;)) 

DT[, .(N=seq_len(.N)), by=.(x,y)]$N # 上面相当于做了这样的事
# 应用
dcast(DT, x ~ rowid(x, prefix=&#34;group&#34;), value.var=&#34;z&#34;) #
</code></pre><ul>
<li><strong>tstrsplit</strong>      &mdash;字符串拆分函数，类似<code>strsplit</code>函数,只不过结果和<code>strsplit</code>进行了转置</li>
</ul>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">name &lt;- 1:3
dates &lt;- c(&#34;2016-3-4&#34;,&#34;2016-3-14&#34;,&#34;2016-3-24&#34;)
nd &lt;- data.table(name,dates)
nd
strsplit(dates,&#34;-&#34;)
tstrsplit(dates,&#34;-&#34;) 
nd[,c(&#34;year&#34;,&#34;month&#34;,&#34;day&#34;):=tstrsplit(dates,&#34;-&#34;)] # 实现拆分
nd
</code></pre><h2 id="6其他操作">6、其他操作</h2>
<table>
<thead>
<tr>
<th>函数</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>%between%</code></td>
<td>快速查找某一区间：<br><code> mtcars_dt[disp %between% c(150,200)]# 150&lt;= disp &lt;= 200之间</code><br><code> DT[c %between% list(a,b)]#a列 &lt;= c &lt;=b 列之间(向量版本)</code></td>
</tr>
<tr>
<td><code>%chin%</code></td>
<td>快速匹配 （%in% 的加速版）：  x %chin% table</td>
</tr>
<tr>
<td><code>%inrange%</code></td>
<td>快速查找某一区间：<br> <code>dft[V1 %inrange% c(50,60)]</code>  即选择<code>50 &lt;= V1 &lt;=60</code>所有的行<br><code>dft[V1 %inrange% list(V2,V3)]</code> 即选择 <code>V2 &lt;= V1 &lt;= V3</code>的所有行</td>
</tr>
<tr>
<td><code>A %like% B</code></td>
<td><strong>匹配字符串A中含有B的字符</strong></td>
</tr>
<tr>
<td><code>.I</code></td>
<td>表示（分组后）每一行在原数据框中是第几行  dft[,.I[2],by=accept]<br>.I是一个整数向量，等于seq_len(nrow(x)), While grouping, it holds for each item in the group, its row location in x. This is useful to subset in j; <br>e.g.<code> DT[, .I[which.max(somecol)], by=grp].</code>  结合by,提取子集时,非常有用</td>
</tr>
<tr>
<td><code>.N</code></td>
<td>.N 代表行的数量，用by参数分组时则是每一组的行数量</td>
</tr>
<tr>
<td><code>.SD</code></td>
<td>是经过<code>i</code> 和<code>by</code> 处理之后剩下的那部分数据集,本质是一个<code>data.table</code></td>
</tr>
<tr>
<td><strong><code>.SDcols</code></strong></td>
<td>.SDcols 指定.SD 代表的数据框包括哪些列</td>
</tr>
<tr>
<td><code>setDF(DT)</code></td>
<td>将data.table转化为data.frame</td>
</tr>
<tr>
<td><code>setDT(df)</code></td>
<td>将data.frame转化为data.table</td>
</tr>
<tr>
<td><code>setnames(DT,old,new)</code></td>
<td>修改列名 也可以通过重新赋值操作 colnames(DT)</td>
</tr>
<tr>
<td><code>fsort</code></td>
<td>排序</td>
</tr>
<tr>
<td><code>frank</code></td>
<td>求秩, 类似rank</td>
</tr>
<tr>
<td><code>fintersect(x, y, all = FALSE)</code></td>
<td>x与y的交集,相比于基础函数(默认为FALSE)， 增加了all参数，控制重复值</td>
</tr>
<tr>
<td><code>fsetdiff(x, y, all = FALSE)</code></td>
<td>x与y的差集，即x-y</td>
</tr>
<tr>
<td><code>funion(x, y, all = FALSE)</code></td>
<td>x与y的并集</td>
</tr>
<tr>
<td><code>fsetequal(x, y)</code></td>
<td>检验x与y二者是否完全相等,返回逻辑值</td>
</tr>
<tr>
<td><code>shift(x,n=1L,...)</code></td>
<td>把向量x向前移动或者向后移动n个数字</td>
</tr>
</tbody>
</table>
<h3 id="61--between---与-inrange-的区别">6.1  <code>%between%</code>   与 <code>inrange()</code> 的区别</h3>
<p>两者都是选择某列的值在一个范围内的所有行,即 $a \leq c \leq b$</p>
<p><code>DT[c %between% list(a,b)]</code> 这里的a,b 一定是DT自身的列名</p>
<p><code>DT[c %inrange% list(a,b)]</code>  这里的a,b 不是DT自身的列名,可以是外部的变量</p>
<h3 id="62-shift-把向量x向前移动或者向后移动n个数字">6.2 <code>shift()</code> 把向量x向前移动或者向后移动n个数字</h3>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">DT &lt;- data.table(A=1:5)
DT[ , X := shift(A, 1, type=&#34;lag&#34;)]
DT[ , Y := shift(A, 1, type=&#34;lead&#34;)]
DT[ , Y1 := shift(A, 2, type=&#34;lead&#34;)]
DT
</code></pre><h3 id="63--i--返回匹配的行号">6.3  <code>.I()</code>  返回匹配的行号</h3>
<p>由于data.table 没有行号,因此<code>.I()</code>一般不单独使用</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>mtcars_dt <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">data.table</span>(mtcars) 
</span></span><span style="display:flex;"><span>mtcars_dt[, .I[cyl<span style="color:#f92672">==</span><span style="color:#ae81ff">6</span>]] <span style="color:#75715e"># 返回 cyl ==6 所在的行号</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## 等价于</span>
</span></span><span style="display:flex;"><span>mtcars_dt[, <span style="color:#a6e22e">which</span>(cyl<span style="color:#f92672">==</span><span style="color:#ae81ff">6</span>)]
</span></span></code></pre></div><h3 id="64-sd--是经过i和by处理之后剩下的那部分数据集">6.4 <code>.SD </code> 是经过<code>i</code> 和<code>by</code> 处理之后剩下的那部分数据集</h3>
<p><strong><code>.SD</code>代表行经过<code>i</code> 筛选后, 列除了<code>by</code>参数指定的列以外的所有列组成的新的data.table, 是原数据的子集</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span><span style="color:#a6e22e">library</span>(data.table)
</span></span><span style="display:flex;"><span>mtcars_dt <span style="color:#f92672">=</span> data.table<span style="color:#f92672">::</span><span style="color:#a6e22e">as.data.table</span>(mtcars)
</span></span><span style="display:flex;"><span>mtcars_dt[, .SD, by<span style="color:#f92672">=</span>cyl]
</span></span><span style="display:flex;"><span>output <span style="color:#f92672">&lt;-</span> mtcars_dt[, <span style="color:#a6e22e">lapply</span>(.SD[, <span style="color:#ae81ff">1</span><span style="color:#f92672">:</span><span style="color:#ae81ff">10</span>, with<span style="color:#f92672">=</span>F], mean), by<span style="color:#f92672">=</span>cyl]
</span></span><span style="display:flex;"><span>output
</span></span></code></pre></div><h2 id="7--set-函数可以加快循环">7  set() 函数可以加快循环</h2>
<p><code>set(x, i = NULL, j, value)</code></p>
<p>作用:  将value 值快速分配给i行j列元素, <code>i</code> , <code>j</code> 使用整数<code>10L</code> 而不是<code>10</code>, j参数不能省</p>
<pre tabindex="0"><code class="language-{r}" data-lang="{r}">m = matrix(1,nrow=3,ncol=4)
DT = as.data.table(m)    
set(DT,3L,1L,10)# 第3行第1列元素改为10
set(DT,,2L,20) # 第2列的所有元素都改为20
DT


m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)  
DT2 = copy(DT)
system.time(for (i in 1:10000) DF[i,1] &lt;- i)
system.time(for (i in 1:10000) DT[i,V1:=i])
system.time(for (i in 1:10000) set(DT2,i,1L,i*10))
</code></pre><h2 id="8options设置">8、options设置</h2>
<p>在控制台中输入options()会打印出一个list，这是当前的options设置值，比如显示保留几位小数等。加载data.table包之后，这里新增了一些data.table专用的参数，可以用下面的命令查看</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-R" data-lang="R"><span style="display:flex;"><span>ops <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">options</span>() <span style="color:#75715e"># ops就是一个list，参数和值的一一对应</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 由于data.table专用参数都是以datatable为前缀，使用我们输入时可以这样</span>
</span></span><span style="display:flex;"><span>ops<span style="color:#f92672">$</span>datatable.print.nrows <span style="color:#75715e"># 返回100，设置打印的最大行数，超过了则简单打印</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">getOption</span>(<span style="color:#e6db74">&#34;datatable.print.topn&#34;</span>) <span style="color:#75715e">#返回5，简单打印设置，前后各5行，其余行省略</span>
</span></span></code></pre></div>
        </section>
    </div>
    <br>
    
    




<span id="/md/2018-01-17-datatable2/" class="leancloud_visitors" data-flag-title="data.table -- 2基本概念">
  <span class="post-meta-item-text">文章总阅读量 </span>
  <span class="leancloud-visitors-count"><i class="leancloud-visitors-count"></i></span>次;
  <p></p>
</span>



    

    
    
    <button id="edit-button" class="icon-button" type="button" title="Fork and edit" aria-label="Fork and edit" aria-haspopup="true" aria-expanded="false" aria-controls="edit">
        <i class="fa fa-edit">编辑本文</i>
    </button>
    
    
    

    <br>
    <hr>
    <li style="float:left;list-style:none">
        
        <a class="previous" href="/md/2018-01-16-datatable1/"> 上一篇: data.table -- 1基本函数</a>
        
    </li>
    <li style="float:right;list-style:none">
        
        <a class="next" href="/md/2018-01-18-datatable3/"> 下一篇: data.table -- 3常见操作</a>
        
    </li>
     
    
    <script src="/js/copyCode.js"></script>
    <script src="/js/tooltips.js"></script>
    
   
    <script>
    [].slice.call(document.querySelectorAll('table')).forEach(function(el) {
        var wrapper = document.createElement('div');
        wrapper.className = 'table-area';
        el.parentNode.insertBefore(wrapper, el);
        el.parentNode.removeChild(el);
        wrapper.appendChild(el);
        $("table").wrap("<div class='table-area'></div>");
    })
    </script>

    
<br>
<hr>


<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-111691389-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('js', new Date());

  gtag('config', 'UA-111691389-1');
</script>




      
      
      

       
      
      
      <script>
              document.getElementById("edit-button").addEventListener("click", function () {
                  var editWindow = window.open("https:\/\/github.com\/zoushucai\/blogmmm/edit/master/content/md\/2018-01-17-datatable2.md");
              });</script>
      
          




<script>
  function resizeIframe(obj) {
    obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
  } 
</script>



    </style>
    <script type="text/javascript">
    function showdiv(){
        document.getElementById("divtocTableOfContents").style.display="block";
        document.getElementById("strHref").innerHTML="目录收起-";
        document.getElementById('divTableOfContents').style.width="22%";
        document.getElementById('divTableOfContents').style.height="55%";
        document.getElementById('divTableOfContents').style.top="25%";
        document.getElementById('divTableOfContents').style.bottom="5%";
        document.getElementById("strHref").href="javascript:hidediv()";
    }
    function hidediv(){
        document.getElementById("divtocTableOfContents").style.display="none";
        document.getElementById("strHref").innerHTML="目录展开+";
        document.getElementById("strHref").href="javascript:showdiv()";
        document.getElementById('divTableOfContents').style.width="10%";
        document.getElementById('divTableOfContents').style.height="5%";
    }
    </script>
</body>

</html>
</div> 







    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/mathtex-script-type.min.js" integrity="sha384-LJ2FmexL77rmGm6SIpxq7y+XA6bkLzGZEgCywzKOZG/ws4va9fUVu2neMjvc3zdv" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js"></script>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            renderMathInElement(document.body, {
            delimiters: [
                            {left: "$$", right: "$$", display: true},
                            {left: "$", right: "$", display: false},
                            {left: "\\(", right: "\\)", display: false},
                            {left: "\\[", right: "\\]", display: true}
                        ]
            });
        });
    </script>













<br>
<div class="inner">
              
            
          
          
  
          
  
  <div id="vcomments"></div>
  
  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  
  <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
  <script type="text/javascript">
    new Valine({
        el: '#vcomments' ,
        appId: 'HfHPKPkLa0cBEDPcdBAHuqMv-gzGzoHsz',
        appKey: 'r5RJAasN8e0mB9sq6y9pEcX0',
        lang:'zh-CN',
        notify:  false , 
        verify:  false  ,
        avatar:'identicon', 
        placeholder: '说点什么吧...',
        visitor:  true 
    });
  </script>

</div>

<br>
<br>
<footer>
    <p style="float:right;margin-right: 5%;margin-top: 0%;">
        &copy; 2022 <a href="https://github.com/zoushucai">zsc</a>
      </p>
</footer>
<br>
<br>


